package com.kedou.sdk.ui.content;

import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import com.kedou.sdk.ui.view.FloatWindowView;
import com.kedou.sdk.utils.WL;
import com.kedou.sdk.utils.XmlUtils;

/**
 * Created by AiBin on 2017/6/10.
 */

public final class FloatWindowManager implements View.OnTouchListener, Handler.Callback {

    private static final String TAG = FloatWindowManager.class.getSimpleName();
    private static final int MAX_OFFSET = 5;
    private static final int MAX_SHOW_TIMEOUT = 3 * 1000;
    private static final int MAX_ADSORB_EDGE_TIMEOUT = 5 * 1000;
    private static final int MAX_START_MOVE_TIMEOUT = 100;

    private static final int MSG_HIDE_FLOAT_WINDOW = 0;
    private static final int MSG_ADSORB_FLOAT_WINDOW = 1;
    private static final int MSG_START_MOVE_WINDOW = 2;

    private final WindowManager mWindowManager;
    private final WindowManager.LayoutParams mLayoutParams;
    private final Handler mHandler;

    private FloatWindowView mWindowView;
    private Point mOldPoint = new Point();
    private volatile boolean isActivated = true;
    private volatile boolean isAddedWindow = false;
    private volatile boolean isCanMove = false;

    private byte[] mLock = new byte[0];

    private int mLastPositionY = 0;
    private int mScreenHeight = 0;


    public FloatWindowManager(WindowManager manager) {
        this.mWindowManager = manager;
        this.mLayoutParams = new WindowManager.LayoutParams();
        this.mHandler = new Handler(Looper.getMainLooper(), this);
        initWindowManagerValues();
    }

    void initWindowManagerValues() {
        DisplayMetrics metric = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(metric);
        mScreenHeight = metric.heightPixels;

        WL.d(TAG, "initWindowManagerValues ----> screenHeight: " + mScreenHeight);

        mLayoutParams.type = WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
//        mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
        mLayoutParams.format = PixelFormat.TRANSLUCENT;
        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//                |WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN;
        mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        if(XmlUtils.isRedPackageChannel()){
            mLayoutParams.x = metric.widthPixels/3;
            mLayoutParams.y = 0;
        }else {
            mLayoutParams.x = 0;
            mLayoutParams.y = mScreenHeight / 4;
        }
//

        mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
    }

    public void setOnFloatWindowClickListener(FloatWindowView.OnFloatWindowClickListener listener) {
        if (this.mWindowView != null) {
            this.mWindowView.setOnFloatWindowClickListener(listener);
        }
    }

    public void addWindowView(FloatWindowView view) {
        WL.d(TAG, "addWindowView ---->");
        addWindowView(view, MAX_ADSORB_EDGE_TIMEOUT);
    }

    public void addWindowView(FloatWindowView view, long delayMillis) {
        WL.d(TAG, "addWindowView ---->");
        synchronized (mLock) {
            this.mWindowView = view;
            if(!XmlUtils.isRedPackageChannel()){
                this.mWindowView.setOnTouchListener(this);
            }
                //不可移动
//            this.mWindowView.setOnTouchListener(this);
            mWindowManager.addView(this.mWindowView, mLayoutParams);
            isAddedWindow = true;
        }
        if(!XmlUtils.isRedPackageChannel()){
            Message msg = mHandler.obtainMessage(MSG_ADSORB_FLOAT_WINDOW);
            mHandler.sendMessageDelayed(msg, delayMillis);
        }

    }

    public void removeWindowView(View view) {
        WL.d(TAG, "removeWindowView ---->");
        synchronized (mLock) {
            mWindowManager.removeView(view);
            isAddedWindow = false;
        }
    }

    public boolean isAddedWindow() {
        WL.d(TAG, "isAddedWindow ---->" + isAddedWindow);
        return isAddedWindow;
    }

    public final boolean isActivated() {
        final boolean activated = this.isActivated;
        this.isActivated = true;
        return activated;
    }

    public void clearAllMessage() {
        mHandler.removeMessages(MSG_ADSORB_FLOAT_WINDOW);
        mHandler.removeMessages(MSG_HIDE_FLOAT_WINDOW);
    }

    public void updateWindowViewY(boolean isShowMessageWindow) {
        if (mWindowManager != null && mLayoutParams != null) {
            if (isShowMessageWindow) {
                this.mLastPositionY = mLayoutParams.y;
                mLayoutParams.y = mScreenHeight / 10;
            } else {
                mLayoutParams.y = this.mLastPositionY;
            }
            mWindowManager.updateViewLayout(this.mWindowView, mLayoutParams);
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (!mWindowView.isSupportGesture()) {
            return false;
        }

        final int action = motionEvent.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                mHandler.removeMessages(MSG_ADSORB_FLOAT_WINDOW);
                mHandler.removeMessages(MSG_HIDE_FLOAT_WINDOW);
                mHandler.removeMessages(MSG_START_MOVE_WINDOW);
                mHandler.sendEmptyMessageDelayed(MSG_START_MOVE_WINDOW, MAX_START_MOVE_TIMEOUT);

                mOldPoint.x = mLayoutParams.x;
                mOldPoint.y = mLayoutParams.y;
                mWindowView.setImageResource();
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                if (isCanMove) {
                    final int viewWidth = view.getMeasuredWidth() / 2;
                    final int viewHeight = view.getMeasuredHeight() / 2;

                    mLayoutParams.x = (int) motionEvent.getRawX() - viewWidth;
                    mLayoutParams.y = (int) motionEvent.getRawY() - viewHeight;
                    mWindowManager.updateViewLayout(this.mWindowView, mLayoutParams);
                }
                break;
            }

            case MotionEvent.ACTION_UP: {
                mHandler.removeMessages(MSG_START_MOVE_WINDOW);
                isCanMove = false;

                DisplayMetrics metric = new DisplayMetrics();
                mWindowManager.getDefaultDisplay().getMetrics(metric);
                final int screenCenterWidth = metric.widthPixels;
                final int viewWidth = view.getMeasuredWidth();
                final int windowCenterX = mLayoutParams.x + viewWidth / 2;
                if (windowCenterX <= screenCenterWidth / 2) {
                    mLayoutParams.x = 0;
                    mWindowView.setWindowGravity(Gravity.LEFT);
                } else {
                    final int screenCenterHeight = metric.heightPixels;
                    mLayoutParams.x = Math.max(screenCenterWidth, screenCenterHeight);
                    mWindowView.setWindowGravity(Gravity.RIGHT);
                }
                mWindowManager.updateViewLayout(this.mWindowView, mLayoutParams);

                Message msg = mHandler.obtainMessage(MSG_ADSORB_FLOAT_WINDOW);
                mHandler.sendMessageDelayed(msg, MAX_ADSORB_EDGE_TIMEOUT);

                final int offsetX = Math.abs(mOldPoint.x - mLayoutParams.x);
                final int offsetY = Math.abs(mOldPoint.y - mLayoutParams.y);
                if (!(offsetX < MAX_OFFSET && offsetY < MAX_OFFSET)) {
                    this.isActivated = true;
                }
                return !(offsetX < MAX_OFFSET && offsetY < MAX_OFFSET);
            }

            default:
                WL.d(TAG, "onTouch -----> action: " + action);
        }

        return false;
    }

    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_HIDE_FLOAT_WINDOW: {
                mWindowView.setAlpha(0.9f);
                isActivated = false;
                break;
            }

            case MSG_ADSORB_FLOAT_WINDOW: {
                isActivated = false;
                if (mLayoutParams.x > 0) {
                    mWindowView.setRightImageResource();
                } else {
                    mWindowView.setLeftImageResource();
                }

                mHandler.removeMessages(MSG_ADSORB_FLOAT_WINDOW);
                mHandler.removeMessages(MSG_HIDE_FLOAT_WINDOW);
                Message hideMsg = mHandler.obtainMessage(MSG_HIDE_FLOAT_WINDOW);
                mHandler.sendMessageDelayed(hideMsg, MAX_SHOW_TIMEOUT);
                break;
            }

            case MSG_START_MOVE_WINDOW: {
                isCanMove = true;
            }

            default:
                WL.d(TAG, "handleMessage ---> message what is not e");
        }
        return true;
    }

}
